package indi.zhifa.engine.mpenhance.handler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.nio.ByteBuffer;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@MappedTypes(Long[].class)
@MappedJdbcTypes(JdbcType.BINARY)
public class LongArrayTypeHandler extends BaseTypeHandler<Long[]> {

    public LongArrayTypeHandler() {
    }

    protected byte[] longArrToByteArray(final Long[] longArr) {
        ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES * longArr.length);
        for (long value : longArr) {
            buffer.putLong(value);
        }
        byte[] byteArray = buffer.array();
        return byteArray;
    }

    protected Long[] byteArrToLongArray(final byte[] byteArr) {
        ByteBuffer buffer = ByteBuffer.wrap(byteArr);
        Long[] rtn = new Long[buffer.remaining() / Long.BYTES];
        int idx = 0;
        while (buffer.hasRemaining()) {
            rtn[idx++] = buffer.getLong();
        }
        return rtn;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Long[] parameter, JdbcType jdbcType) throws SQLException {
        ps.setBytes(i, longArrToByteArray(parameter));
    }

    @Override
    public Long[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
        byte[] bytes = rs.getBytes(columnName);
        return this.getBytes(bytes);
    }

    @Override
    public Long[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        byte[] bytes = rs.getBytes(columnIndex);
        return this.getBytes(bytes);
    }

    @Override
    public Long[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        byte[] bytes = cs.getBytes(columnIndex);
        return this.getBytes(bytes);
    }

    private Long[] getBytes(byte[] bytes) {
        Long[] returnValue = null;
        if (bytes != null) {
            returnValue = byteArrToLongArray(bytes);
        }
        return returnValue;
    }
}
